<pre class='metadata'>
Group: WG21
Title: Relax Requirements for time_point::clock
Status: P
Shortname: P2212
Revision: 2
Editor: Alexey Dmitriev, cpplang@admitriev.name
Editor: Howard Hinnant, howard.hinnant@gmail.com
TR: https://wg21.link/P2212
URL: https://wg21.link/P2212R2
No Abstract: yes
Markup shorthands: markdown yes
</pre>

# Abstract # {#abstract}

We propose to relax the requirements on the `Clock` template parameter of `std::chrono::time_point`.

# Revision History # {#changelog}
## Revision 2 ## {#r2}
Add proposed wording for [**thread.req.paramname**] per Tim Song's suggestion.

Rebase proposed wording to the current working draft.
## Revision 1 ## {#r1}
Alter proposed wording per Jonathan Wakely's suggestion.
## Revision 0 ## {#r0}
Initial revision.

# Motivation # {#motivation}

It is sometimes useful to give `time_point` a `Clock` template
argument that does not meet the *Cpp17Clock* requirements. The most obvious use
case is the `local_t` introduced in C++20.  This "clock" is not really a clock
at all. It has no functionality for getting the current time.  Nevertheless, C++20
utilizes `time_point<local_t, Duration>` to represent a family of
time points that do not represent instants in time until they are paired with a specific `time_zone`.  This gives "local time" a distinct type from "system/UTC time"
in order to reduce the possibility of the programmer confusing these two types in their code.

Since the introduction of `local_t`, more use cases for "not-quite-clocks" have become apparent:

* [Some people need a stateful clock](https://stackoverflow.com/q/56400313/576911).
    This requires a non-static `now()` function.

* <a href="https://stackoverflow.com/q/56721494/576911">Some people would like to represent "time of day" as a distinct <code class="highlight"><c- n>time_point</code></a>.

* It is sometimes useful to represent time points as defined by some external system
    not controlled by you, where you can't generate the current time_point easily or at all.

    One example might be value of timestamp counter on different computer.
    You can't easily generate the current value, but you can still meaningfully manipulate existing values generated by other means: compare them, calculate differences between them, etc.

# Wording # {#wording}

Remove paragraph 1 in [**time.point.general**]:

<del>Clock shall either meet the *Cpp17Clock* requirements ([**time.clock.req**]) or be the type `local_t`.</del>

Edit the last sentence of paragraph 1 in [**thread.req.paramname**] as indicated:

If a template parameter is named `Clock`, the corresponding template
argument shall be a type `C` <ins>that meets the *Cpp17Clock* requirements
([**time.clock.req**]); the program is ill-formed if `is_clock_v<C>` is
false.</ins><del>for which `is_clock_v<C>` is `true`; otherwise the
program is ill-formed.</del>

# Effect on existing code # {#existing-code}

This change should not affect any conforming code because the requirement is only relaxed.

# Effect on implementations # {#implementation}

This change should not have an effect on most of implementations because in practice they do not use any of the members of `Clock` outside of **[thread]**.
**[thread.req.paramname]** places additional requirements on the `Clock` template parameter, namely that `is_clock_v<Clock>` is `true`.
This change is effectively already proven to be safe because of the existence of `std::chrono::time_point<std::chrono::local_t, Duration>`, where `std::chrono::local_t` is an empty class.

# Acknowledgement # {#acknowledgement}
Thanks to all those who provided the motivating use cases for this change.
